
#include <asm.h>

.global C_SYMBOL(SetColorARGB32_Raw)

C_SYMBOL(SetColorARGB32_Raw):
R7= -0x24
R6= -0x20
height= -0x1C
SrcStep= -0x18
step= -0x14
ROIwidth= -0x10

argHeight = 0x0;
argDstPitch = 0x4;
argColor = 0x8;
argSrcOpacity = 0xC;

    MOV     R12, SP
    STMFD   SP!, {R4-R12,LR}
    LDR     R4, [R12,#argDstPitch]

    MUL     R5, R4, R2

    ADD     R1, R5, R1, LSL#2
    ADD     R1, R0, R1

    LDR     R4, [R12,#argHeight]
    LDR     R5, [R12,#argColor]
    LDR     R6, [R12,#argSrcOpacity]
    LDR     R2, [R12,#argDstPitch]

//    MOV    R4, R3                       //height
//    MOV    R3, R2                       //width
//    MOV    R2, R1                       //dstPitch
//    MOV    R1, R0                       //pDst
//.long 0xe7fddefe

    AND     R6, R6, #0xFF
    CMP     R6, #0xFF
    BLT     _Start_T_

    MOV R3, R3, LSL #2
    SUB	R2, R2,	R3
    MOV     R11, R5
    MOV     R10, R5
    MOV     R9, R5
    MOV     R8, R5

_lc010_000413_:
    MOV	R5, R3
    ADD	R6, R1,	#7
    BIC	R6, R6,	#7
    SUB	R6, R6,	R1
    CMP	R6, #0
    BEQ	_lc030_000440_

_lc020_000428_:
    CMP	R6, R5
    MOVGT	R6, R5
    SUB	R5, R5,	R6

_lc021_000432_:
    SUBS	R6, R6,	#4
    STR   R11, [R1], #4
    BGT	_lc021_000432_
    CMP	R5, #0
    BEQ	_lc060_000464_

_lc030_000440_:
    SUBS	R5, R5,	#0x10
    ADDMI	R6, R5,	#0x10
    ADDMI	R5, R5,	#0x10
    BMI	_lc020_000428_

_lc040_000449_:
    STMIA   R1!, {R8-R11}

//    STR    R8, [R1], #4
//    STR    R9, [R1], #4
//    STR    R10, [R1], #4
//    STR    R11, [R1], #4
    SUBS	R5, R5,	#0x10
//    STMIA   R1!, {R8-R11}

    BGE	_lc040_000449_
    ADDS	R5, R5,	#0x10
    MOVGT	R6, R5
    BGT	_lc020_000428_

_lc060_000464_:
    ADD	R1, R1,	R2
//    .long 0xe7fddefe
    SUBS	R4, R4,	#1
    BGT	_lc010_000413_

    LDMFD   SP, {R4-R11,SP,PC}

_Start_T_:
    CMP   R6, #0
    ADDEQ     SP, SP, #0x4C
    LDMEQFD   SP, {R4-R11,SP,PC}

    SUB SP, SP, #0x4C

    MOV R3, R3, LSL #2
    STR R3, [SP,#0x4C+ROIwidth]

    MOV R12, R6

    LDR R11, =0x00FF00FF

    AND   R7, R11, R5               //R3:0G0B
    AND   R8, R11, R5, LSR #8       //R4:0A0R
    MUL   R9, R7, R12
    MUL   R10, R8, R12

    AND   R9, R9, R11, LSL #8
    AND   R10, R10, R11, LSL #8

    ORR   R5, R10, R9, LSR #8

    RSB   R12, R12, #0xFF

    MOV LR, R1
    SUB	R2, R2,	R3                          //R3 = DST pitch - ROI width
    STR R2, [SP,#0x4C+step]

_Line_Start_T_:
    LDR  R3, [SP,#0x4C+ROIwidth]
    MOV	R6, R3                              //R6 = ROI width
    ADD	R7, LR,	#7                          //R2 = destination pointer
    BIC	R7, R7,	#7                          //Ceiling R7 ADDRESS to 8 byte aligned, suppose jumped N
    SUB	R7, R7,	LR                          //
    CMP	R7, #0                              //Compare to see if R7 is originally 8 byte aligned
    BEQ	_lc030_000669_T_                    //if so jump to _lc030_000669_T_

_Less_Than_32_T_:

//    LDR   R2 ,[R0], #4
    LDR   R8 ,[LR]

    CMP	R7, R6                              //
    MOVGT	R7, R6                          //Let R7 be the min(N , width)
    SUB	R6, R6,	R7                          //Let R6 be width - N
    STR R6, [SP,#0x4C+R6]

_Process_Step_N_header_T_:

    SUBS  R7, R7, #4

    AND   R0, R11, R8               //GB
    MUL   R2, R0, R12
    AND   R1, R11, R8, LSR #8       //AR
    MUL   R6, R1, R12
    LDRGT   R8 ,[LR, #4]
    MOV   R2, R2, LSR #8            //GB
    MOV   R6, R6, LSR #8            //AR
    AND   R2, R2, R11
    AND   R6, R6, R11

    ADD   R2, R2, R9
    ADD   R6, R6, R10

    ORR   R5, R2, R6, LSL #8

    STR   R5, [LR], #4

    BGT	_Process_Step_N_header_T_
    LDR R6, [SP,#0x4C+R6]
    CMP	R6, #0
    BEQ	_Next_Line_T_

_lc030_000669_T_:
    SUBS	R6, R6,	#0x10                   //R6 -= 32 byte
    ADDMI	R7, R6,	#0x10
    ADDMI	R6, R6,	#0x10
    BMI	    _Less_Than_32_T_                      //jumpt to _Less_Than_32_T_ if less than 32 byte


    LDR   R8 ,[LR]
    STR   R7, [SP,#0x4C+R7]

_Loop_Aligned8_T_:

//    SUBS	R10, R6,	#0x40
//    LDRGT   R1, [R0, #0x3C]                     //Preload

    AND   R0, R11, R8               //GB
    MUL   R2, R0, R12
    SUBS  R6, R6,	#0x10
    AND   R1, R11, R8, LSR #8       //AR
    MUL   R7, R1, R12
    LDR   R8 ,[LR, #4]
    AND   R2, R2, R11, LSL #8
    AND   R7, R7, R11, LSL #8
    ORR   R1, R7, R2, LSR #8
    ADD   R1, R1, R5
    STR   R1, [LR], #4

    AND   R0, R11, R8               //GB
    MUL   R2, R0, R12
    AND   R1, R11, R8, LSR #8       //AR
    MUL   R7, R1, R12
    LDR   R8 ,[LR, #4]
    AND   R2, R2, R11, LSL #8
    AND   R7, R7, R11, LSL #8
    ORR   R1, R7, R2, LSR #8
    ADD   R1, R1, R5
    STR   R1, [LR], #4

    AND   R0, R11, R8               //GB
    MUL   R2, R0, R12
    AND   R1, R11, R8, LSR #8       //AR
    MUL   R7, R1, R12
    LDR   R8 ,[LR, #4]
    AND   R2, R2, R11, LSL #8
    AND   R7, R7, R11, LSL #8
    ORR   R1, R7, R2, LSR #8
    ADD   R1, R1, R5
    STR   R1, [LR], #4

    AND   R0, R11, R8               //GB
    MUL   R2, R0, R12
    AND   R1, R11, R8, LSR #8       //AR
    MUL   R7, R1, R12
    LDRGE   R8 ,[LR, #4]
    AND   R2, R2, R11, LSL #8
    AND   R7, R7, R11, LSL #8
    ORR   R1, R7, R2, LSR #8
    ADD   R1, R1, R5
    STR   R1, [LR], #4

    BGE	_Loop_Aligned8_T_

//.long 0xe7fddefe

    LDR   R7, [SP,#0x4C+R7]
    ADDS	R6, R6,	#0x10
    BEQ	_Next_Line_T_
    MOVGT	R7, R6
    BGT	_Less_Than_32_T_

_Next_Line_T_:
    LDR R3, [SP,#0x4C+step]
    ADD	LR, LR,	R3
    SUBS	R4, R4,	#1

    BGT	_Line_Start_T_
    ADD     SP, SP, #0x4C
    LDMEQFD   SP, {R4-R11,SP,PC}
